-- showme是直接勾setstring 然后加了一堆\n, insight应该是自己弄了富文本,算了一下行数,然后也是加了一堆\n
-- local function fix_str(s)
--     return string.gsub(s,'[%s\n]+$','')
-- end

-- AddClassPostConstruct('widgets/hoverer',
-- ---comment
-- ---@param self widget_hoverer
-- function (self)
--     local old_OnUpdate = self.OnUpdate
--     function self:OnUpdate(...)

--         old_OnUpdate(self,...)
--         local extend_text = '测试你'
--         local fixed = '\n'..extend_text..' \n \n \n'
--         local new_str = fix_str(self.text.string or '') .. fixed
--         self.text.string = new_str
--         self.text.inst.TextWidget:SetString(new_str)
--         -- self.text:SetString((self.text:GetString() or '') .. t)
--         local pos = TheInput:GetScreenPosition()
--         self:UpdatePosition(pos.x, pos.y)
--     end
-- end)

-- 故 谁都不管了 我直接放右上角 

if TUNING.MOD_WEBBER_THE_TRAINER.map_nutrients == nil then
    ---获取农作物的肥料消耗和产出
    ---@type table<string,{nutrient: table<integer,string|number>, seasons: {spring:boolean|nil,summer:boolean|nil,autumn:boolean|nil,winter:boolean|nil}}>
    TUNING.MOD_WEBBER_THE_TRAINER.map_nutrients = {}
end
AddSimPostInit(function ()
    if TheWorld then
        TheWorld:DoTaskInTime(0,function ()
            local farm_plant_defs = require('prefabs/farm_plant_defs').PLANT_DEFS
            for k,v in pairs(farm_plant_defs) do
                if GLOBAL.Prefabs[k..'_seeds'] and GLOBAL.Prefabs['farm_plant_'..k] then
                    local nutrient_consumption = v.nutrient_consumption
                    TUNING.MOD_WEBBER_THE_TRAINER.map_nutrients[k..'_seeds'] = {nutrient = {},seasons = {}}
                    TUNING.MOD_WEBBER_THE_TRAINER.map_nutrients['farm_plant_'..k] = {nutrient = {},seasons = {}}
                    local total_consume = 0
                    local dont_consume_count = 0
                    for i,consume in ipairs(nutrient_consumption) do
                        if consume > 0 then
                            total_consume = total_consume + consume
                            TUNING.MOD_WEBBER_THE_TRAINER.map_nutrients[k..'_seeds'].nutrient[i] = - consume
                            TUNING.MOD_WEBBER_THE_TRAINER.map_nutrients['farm_plant_'..k].nutrient[i] = - consume
                        else
                            dont_consume_count = dont_consume_count + 1
                            TUNING.MOD_WEBBER_THE_TRAINER.map_nutrients[k..'_seeds'].nutrient[i] = 0
                            TUNING.MOD_WEBBER_THE_TRAINER.map_nutrients['farm_plant_'..k].nutrient[i] = 0
                        end
                    end
                    local restore = '+'..tostring(total_consume / dont_consume_count)
                    for i,consume in ipairs(TUNING.MOD_WEBBER_THE_TRAINER.map_nutrients[k..'_seeds'].nutrient) do
                        if consume == 0 then
                            TUNING.MOD_WEBBER_THE_TRAINER.map_nutrients[k..'_seeds'].nutrient[i] = restore
                            TUNING.MOD_WEBBER_THE_TRAINER.map_nutrients['farm_plant_'..k].nutrient[i] = restore
                        else
                            TUNING.MOD_WEBBER_THE_TRAINER.map_nutrients[k..'_seeds'].nutrient[i] = tostring(consume)
                            TUNING.MOD_WEBBER_THE_TRAINER.map_nutrients['farm_plant_'..k].nutrient[i] = tostring(consume)
                        end
                    end
                    for season,adapt in pairs(v.good_seasons) do
                        if adapt then
                            TUNING.MOD_WEBBER_THE_TRAINER.map_nutrients[k..'_seeds'].seasons[season] = true
                        end
                    end
                end
            end
        end)
    end
end)

local _lang = SUGAR_webber_the_trainer:getModConfigDataFromTUNING('_lang')
local _hour,_min,_sec = STRINGS.MOD_WEBBER_THE_TRAINER.hovertext.hour,STRINGS.MOD_WEBBER_THE_TRAINER.hovertext.min,STRINGS.MOD_WEBBER_THE_TRAINER.hovertext.sec
---将秒数转成时分秒
---@param t number
---@return string
---@nodiscard
local function format_duration(t)
    local hours = math.floor(t / 3600)
    t = t % 3600
    local minutes = math.floor(t / 60)
    local seconds = t % 60

    local time_str = ""
    if hours > 0 then
        time_str = time_str .. hours .. _hour
    end
    if minutes > 0 then
        time_str = time_str .. minutes .. _min
    end
    if seconds > 0 then
        time_str = time_str .. seconds .. _sec
    end
    if _lang == 'cn' and hours <= 0 and minutes > 0 and  seconds <= 0 then
        time_str = time_str .. '钟'
    end

    return time_str
end

---@type table<string,fun(inst:ent):string>
local hover_text_data = {
    webbert_bread = function (inst)
        local _db = TUNING.MOD_WEBBER_THE_TRAINER.ITEMS.webbert_bread
        return subfmt(STRINGS.MOD_WEBBER_THE_TRAINER.hovertext.webbert_bread,{a = (_db.delta_hunger>0 and '+' or '-')..math.abs(_db.delta_hunger), b = (_db.delta_san>0 and '+' or '-')..math.abs(_db.delta_san), c = (_db.delta_health>0 and '+' or '-')..math.abs(_db.delta_health),duration = format_duration(_db.duration), val = ((1-_db.hungerrate)*100)..'%'})
    end,
    webbert_dish_silkglandegg = function (inst)
        local _db = TUNING.MOD_WEBBER_THE_TRAINER.ITEMS.webbert_dish_silkglandegg
        return subfmt(STRINGS.MOD_WEBBER_THE_TRAINER.hovertext.webbert_dish_silkglandegg,{duration = format_duration(_db.buff_duration), val = (_db.buff_atkspeedadd*100)..'%'})
    end,
    webbert_dish_mushroomsilkjelly = function (inst)
        local _db = TUNING.MOD_WEBBER_THE_TRAINER.ITEMS.webbert_dish_mushroomsilkjelly
        return subfmt(STRINGS.MOD_WEBBER_THE_TRAINER.hovertext.webbert_dish_mushroomsilkjelly,{duration = format_duration(_db.buff_duration), val = _db.buff_walkspeedmult})
    end,
    webbert_dish_sporeglandsoup = function (inst)
        local _db = TUNING.MOD_WEBBER_THE_TRAINER.ITEMS.webbert_dish_sporeglandsoup
        return subfmt(STRINGS.MOD_WEBBER_THE_TRAINER.hovertext.webbert_dish_sporeglandsoup,{duration = format_duration(_db.buff_duration), san = _db.buff_regensan, bp = (_db.buff_bloodpact_modifier * 100)..'%'})
    end,
    webbert_dish_dragoninfernostew = function (inst)
        local _db = TUNING.MOD_WEBBER_THE_TRAINER.ITEMS.webbert_dish_dragoninfernostew
        return subfmt(STRINGS.MOD_WEBBER_THE_TRAINER.hovertext.webbert_dish_dragoninfernostew,{duration = format_duration(_db.buff_duration)})
    end,
    webbert_dish_respawnheart = function (inst)
        local _db = TUNING.MOD_WEBBER_THE_TRAINER.ITEMS.webbert_dish_respawnheart
        return STRINGS.MOD_WEBBER_THE_TRAINER.hovertext.webbert_dish_respawnheart
    end,
}
for k,v in pairs(hover_text_data) do
    AddPrefabPostInit(k,function (inst)
        ---@class ent_has_hover_text_method : ent
        ---@field GetWebbertHoverExtendHint (fun():string)|nil

        ---@cast inst ent_has_hover_text_method

        inst:DoTaskInTime(0,function ()
            local old_GetWebbertHoverExtendHint = inst.GetWebbertHoverExtendHint
            function inst:GetWebbertHoverExtendHint(...)
                local res = old_GetWebbertHoverExtendHint ~= nil and old_GetWebbertHoverExtendHint(self,...) or ''
                return res .. v(inst)
            end
        end)

        if not TheWorld.ismastersim then
            return inst
        end
    end)
end

---@type widget_text
local Text = require 'widgets/text'

---@class widget_hoverer_webbert : widget_hoverer
---@field webbert_text widget_text

AddClassPostConstruct('widgets/hoverer',
---comment
---@param self widget_hoverer_webbert
function (self)
    self.webbert_text = self.text:AddChild(Text(UIFONT, 30))
    self.webbert_text:SetPosition(self.default_text_pos)
    local old_OnUpdate = self.OnUpdate
    function self:OnUpdate(...)
        local res = old_OnUpdate(self,...)
        if self.owner.components.playercontroller == nil or not self.owner.components.playercontroller:UsingMouse() then
            self.webbert_text:SetString('')
        elseif not self.forcehide then
            local tar = TheInput:GetHUDEntityUnderMouse()
            tar = tar and tar.widget and tar.widget.parent and tar.widget.parent.item or TheInput:GetWorldEntityUnderMouse()
            if tar and tar.entity and tar.prefab then
                local tar_prefab = tar.prefab
                local extra_hint = nil
                local extend_hint = tar.GetWebbertHoverExtendHint and tar:GetWebbertHoverExtendHint() or nil

                extra_hint = ''

                if ThePlayer and ThePlayer.prefab == 'webbert' then
                    local farm_plant_seeds,farm_plant_seeds_c = string.gsub(tar_prefab, '_seeds', '')
                    local farm_plant,farm_plant_c = string.gsub(tar_prefab, 'farm_plant_', '')
                    local veggie_name = (farm_plant_seeds_c > 0 and farm_plant_seeds) or (farm_plant_c > 0 and farm_plant) or nil
                    local map_nutrients = TUNING.MOD_WEBBER_THE_TRAINER.map_nutrients
                    if veggie_name and  map_nutrients[veggie_name..'_seeds'] then
                        local displayname = STRINGS.NAMES[string.upper(veggie_name)] or 'MISSING_NAME'
                        extra_hint = extra_hint ..'\n'.. displayname
                        if farm_plant_seeds_c > 0 then
                            extra_hint = extra_hint .. '\n' .. STRINGS.NAMES[string.upper(tar_prefab)]
                        end
                        local nutrient = map_nutrients[veggie_name..'_seeds'] and map_nutrients[veggie_name..'_seeds'].nutrient
                        if nutrient then
                            local str_nutrient = STRINGS.MOD_WEBBER_THE_TRAINER.fertilizer .. ': '
                            for _,v in ipairs(nutrient) do
                                str_nutrient = str_nutrient .. ' ' .. v
                            end

                            extra_hint = extra_hint ..'\n'.. str_nutrient
                        end
                        local seasons = map_nutrients[veggie_name..'_seeds'] and map_nutrients[veggie_name..'_seeds'].seasons
                        if seasons then
                            extra_hint = extra_hint ..'\n'.. STRINGS.MOD_WEBBER_THE_TRAINER.hovertext.season .. ': '
                            for _,v in ipairs({'spring','summer','autumn','winter'}) do
                                if seasons[v] then
                                    extra_hint = extra_hint .. ' ' .. STRINGS.MOD_WEBBER_THE_TRAINER.hovertext[v]
                                end
                            end
                        end
                    end
                end

                local _hint = extra_hint and (extend_hint and (extra_hint .. "\n" .. extend_hint) or extra_hint) or extend_hint
                if _hint and _hint ~= '' then
                    self.webbert_text:SetString(_hint)

                    local pos = TheInput:GetScreenPosition()
                    local scale = self:GetScale()
                    local scr_w, scr_h = TheSim:GetScreenSize()
                    local w = 0
                    -- local h = 0

                    if self.text ~= nil and self.str ~= nil then
                        local w0, h0 = self.text:GetRegionSize()
                        w = math.max(w, w0)
                        -- h = math.max(h, h0)
                    end
                    if self.secondarytext ~= nil and self.secondarystr ~= nil then
                        local w1, h1 = self.secondarytext:GetRegionSize()
                        w = math.max(w, w1)
                        -- h = math.max(h, h1)
                    end

                    w = w * scale.x * .5
                    -- h = h * scale.y * .5

                    local offset = (pos.x > scr_w/2 and -1 or 1) * (w + 100)
                    self.webbert_text:SetPosition(self.default_text_pos + Vector3(offset,50,0))
                end
            else
                self.webbert_text:SetString('')
            end
        end
        return res
    end
end)